package com.appspot.didit.client.workitem;

import java.util.Date;

import com.appspot.didit.client.BaseView;
import com.appspot.didit.client.tag.TagManager;
import com.appspot.didit.client.ui.EnhancedTextBox;
import com.appspot.didit.client.util.Util;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.inject.Inject;

public class WorkitemListPresenterImpl implements WorkitemListPresenter, ChangesListener {
	private final WorkitemServiceAsync workitemService = GWT.create(WorkitemService.class);
	private final View view;
	
	@Inject
    public WorkitemListPresenterImpl(final HandlerManager eventBus, final View view) {

            this.view = view;
            
            bindEvents(eventBus);
	}
	
	private void bindEvents(final HandlerManager eventBus) {
		eventBus.addHandler(WorkitemsLoadedEvent.getType(), 
				new WorkitemsLoadedHandler() {
					public void onWorkitemsLoaded(WorkitemsLoadedEvent event) {
						updateView();
					}	                        
				}
		);
		
		eventBus.addHandler(WorkitemCreatedEvent.getType(), 
				new WorkitemCreatedHandler() {
					public void onWorkitemCreated(WorkitemCreatedEvent event) {
						updateView();
					}	                        
				}
		);
		/*
		eventBus.addHandler(WorkitemChangedEvent.getType(), 
				new WorkitemChangedHandler() {
					public void onWorkitemChanged(WorkitemChangedEvent event) {
						updateWorkitem(event.getRowCount(), eventBus);
					}	                        
				}
		);*/
	}
	
	private void updateView() {
		view.update(WorkitemManager.getInstance().getWorkitemList(), this);
	}
	
	@SuppressWarnings("unchecked")
	private void updateWorkitem(int rowCount) {
		FlexTable table = (FlexTable)(view.getTable());
		Workitem wi = WorkitemManager.getInstance().getWorkitemList().get(rowCount-1);
		String description = ((EnhancedTextBox)table.getWidget(rowCount, 1)).getValue();
		String tagString = ((EnhancedTextBox)table.getWidget(rowCount, 0)).getValue();
		//String duration = ((EnhancedTextBox)table.getWidget(rowCount, 2)).getValue();
		String hour = ((EnhancedTextBox)((FlexTable)table.getWidget(rowCount, 2)).getWidget(0, 0)).getValue();
		String minute = ((EnhancedTextBox)((FlexTable)table.getWidget(rowCount, 2)).getWidget(0, 2)).getValue();
		boolean doUpdate = false;
		if(validate(hour+minute, tagString, new Date())) {
			if(description.trim().equals("")) {
				doUpdate = true;
				description = tagString;
			}
			wi.setDescription(description);
			wi.setDuration(Util.getHoursFromIntegers(Integer.parseInt(hour), Integer.parseInt(minute)));
			TagManager.getInstance().updateTags(wi.getTagString(), tagString, wi);
			wi.setTagString(tagString);
			workitemService.update(wi, new AsyncCallback() {
				public void onFailure(Throwable caught) {
					GWT.log("Failed to update workitem", caught);
	            }
	                    
	            public void onSuccess(Object result) {
	                GWT.log("Successfully updated workitem", null);
	            }
			});
		} else {
			view.update(WorkitemManager.getInstance().getWorkitemList(), this);
		}
		if(doUpdate) {
			view.update(WorkitemManager.getInstance().getWorkitemList(), this);
		}
	}
	
    @SuppressWarnings("deprecation")
	private boolean validate(String duration, String tag, Date date) {
    	String hint = "";
    	boolean valid = true;
    	if(duration == null || duration.trim().equals("")) {
    		hint = hint + "Duration must be provided! ";
    		valid = false;
		} else {
			if(!duration.matches("[0-9]*\\.?[0-9]*")) {
				hint = hint + "Duration should only contain numbers! ";
				valid = false;
			}
			if(duration.matches("[0]*")) {
				hint = hint + "Duration should not be 0! "; 
				valid = false;
			}	
		}
		if(tag.trim().equals("") || tag == null) {
			hint = hint + "Tag must be provided! ";
			valid = false;
		}
		if(date != null) {
			Date today = new Date();
			today.setHours(23);
			today.setMinutes(59);
			today.setSeconds(59);
			
			if(date.after(today)) {
				hint = hint + "Date in the future is not allowed to choose! ";
				valid = false;
			}
			
			//Input is valid only when it was less than 5 days before
			today.setHours(0);
			today.setMinutes(0);
			today.setSeconds(0);
			today.setTime(today.getTime() - 5*24*60*60*1000);
			if(date.before(today)) {
				hint = hint + "Date is invalid! ";
				valid = false;
			}
		} else {
			hint = hint + "Date is invalid! ";
			valid = false;
		}
		if(!valid) {
			MessageBox.alert("Alert", hint, null);
		}
		return valid;
    }

    	
    public View showWorkitemList() {
            return view;
    }

    public BaseView getView() {
            return view;
    }

	@Override
	public void update() {
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public void update(int rowCount) {
		updateWorkitem(rowCount);
	}
}
